use anyhow::Result;
use std::time::{Duration, Instant};
use std::thread;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

mod ftp_client_test;
use ftp_client_test::FtpTestClient;

/// 性能测试结果
#[derive(Debug, Clone)]
pub struct PerformanceMetrics {
    pub operation: String,
    pub duration: Duration,
    pub success: bool,
    pub error: Option<String>,
}

/// 性能测试套件
pub struct PerformanceTestSuite {
    results: Arc<Mutex<Vec<PerformanceMetrics>>>,
}

impl PerformanceTestSuite {
    pub fn new() -> Self {
        Self {
            results: Arc::new(Mutex::new(Vec::new())),
        }
    }
    
    /// 记录性能指标
    fn record_metric(&self, operation: String, duration: Duration, success: bool, error: Option<String>) {
        let metric = PerformanceMetrics {
            operation,
            duration,
            success,
            error,
        };
        
        if let Ok(mut results) = self.results.lock() {
            results.push(metric);
        }
    }
    
    /// 测试连接性能
    pub fn test_connection_performance(&self, iterations: usize) -> Result<()> {
        println!("\n=== 测试连接性能 ===");
        
        for i in 0..iterations {
            let start = Instant::now();
            match FtpTestClient::connect("localhost", 2121) {
                Ok(mut client) => {
                    let duration = start.elapsed();
                    client.read_response()?;
                    client.send_command("QUIT")?;
                    client.expect_response(221)?;
                    
                    self.record_metric(
                        format!("connection_{}", i),
                        duration,
                        true,
                        None,
                    );
                    
                    println!("连接 {}: {:?}", i, duration);
                }
                Err(e) => {
                    let duration = start.elapsed();
                    self.record_metric(
                        format!("connection_{}", i),
                        duration,
                        false,
                        Some(e.to_string()),
                    );
                }
            }
        }
        
        Ok(())
    }
    
    /// 测试命令响应性能
    pub fn test_command_performance(&self, iterations: usize) -> Result<()> {
        println!("\n=== 测试命令响应性能 ===");
        
        let mut client = FtpTestClient::connect("localhost", 2121)?;
        client.read_response()?;
        client.login("testuser", "testpass")?;
        
        let commands = vec![
            "SYST", "PWD", "TYPE I", "NOOP", "FEAT",
        ];
        
        for cmd in commands {
            let mut total_duration = Duration::new(0, 0);
            let mut success_count = 0;
            
            for i in 0..iterations {
                let start = Instant::now();
                match client.send_command(cmd) {
                    Ok(_) => {
                        match client.read_response() {
                            Ok(_) => {
                                let duration = start.elapsed();
                                total_duration += duration;
                                success_count += 1;
                                
                                self.record_metric(
                                    format!("{}_{}", cmd, i),
                                    duration,
                                    true,
                                    None,
                                );
                            }
                            Err(e) => {
                                let duration = start.elapsed();
                                self.record_metric(
                                    format!("{}_{}", cmd, i),
                                    duration,
                                    false,
                                    Some(e.to_string()),
                                );
                            }
                        }
                    }
                    Err(e) => {
                        let duration = start.elapsed();
                        self.record_metric(
                            format!("{}_{}", cmd, i),
                            duration,
                            false,
                            Some(e.to_string()),
                        );
                    }
                }
            }
            
            if success_count > 0 {
                let avg_duration = total_duration / success_count as u32;
                println!("命令 {}: 平均响应时间 {:?} (成功率: {}/{})", 
                    cmd, avg_duration, success_count, iterations);
            }
        }
        
        client.send_command("QUIT")?;
        client.expect_response(221)?;
        
        Ok(())
    }
    
    /// 测试并发性能
    pub fn test_concurrent_performance(&self, concurrent_clients: usize, operations_per_client: usize) -> Result<()> {
        println!("\n=== 测试并发性能 ===");
        
        let results = self.results.clone();
        let mut handles = vec![];
        
        for client_id in 0..concurrent_clients {
            let results = results.clone();
            let handle = thread::spawn(move || -> Result<()> {
                for op_id in 0..operations_per_client {
                    let start = Instant::now();
                    match FtpTestClient::connect("localhost", 2121) {
                        Ok(mut client) => {
                            let connect_duration = start.elapsed();
                            
                            // 记录连接时间
                            results.lock().unwrap().push(PerformanceMetrics {
                                operation: format!("concurrent_connect_{}_{}", client_id, op_id),
                                duration: connect_duration,
                                success: true,
                                error: None,
                            });
                            
                            // 执行操作
                            let op_start = Instant::now();
                            client.read_response()?;
                            client.send_command("SYST")?;
                            client.expect_response(215)?;
                            client.send_command("QUIT")?;
                            client.expect_response(221)?;
                            
                            let op_duration = op_start.elapsed();
                            
                            // 记录操作时间
                            results.lock().unwrap().push(PerformanceMetrics {
                                operation: format!("concurrent_op_{}_{}", client_id, op_id),
                                duration: op_duration,
                                success: true,
                                error: None,
                            });
                        }
                        Err(e) => {
                            let duration = start.elapsed();
                            results.lock().unwrap().push(PerformanceMetrics {
                                operation: format!("concurrent_connect_{}_{}", client_id, op_id),
                                duration,
                                success: false,
                                error: Some(e.to_string()),
                            });
                        }
                    }
                }
                Ok(())
            });
            
            handles.push(handle);
        }
        
        // 等待所有客户端完成
        for (i, handle) in handles.into_iter().enumerate() {
            match handle.join() {
                Ok(Ok(_)) => println!("✅ 并发客户端 {} 完成", i),
                Ok(Err(e)) => println!("❌ 并发客户端 {} 失败: {}", i, e),
                Err(_) => println!("❌ 并发客户端 {} 线程错误", i),
            }
        }
        
        Ok(())
    }
    
    /// 测试文件传输性能
    pub fn test_transfer_performance(&self) -> Result<()> {
        println!("\n=== 测试文件传输性能 ===");
        
        let mut client = FtpTestClient::connect("localhost", 2121)?;
        client.read_response()?;
        client.login("testuser", "testpass")?;
        
        // 测试PASV命令性能
        let start = Instant::now();
        client.send_command("PASV")?;
        client.expect_response(227)?;
        let pasv_duration = start.elapsed();
        
        self.record_metric(
            "pasv_command".to_string(),
            pasv_duration,
            true,
            None,
        );
        
        println!("PASV命令响应时间: {:?}", pasv_duration);
        
        // 测试PORT命令性能
        let start = Instant::now();
        client.send_command("PORT 127,0,0,1,4,210")?;
        client.expect_response(200)?;
        let port_duration = start.elapsed();
        
        self.record_metric(
            "port_command".to_string(),
            port_duration,
            true,
            None,
        );
        
        println!("PORT命令响应时间: {:?}", port_duration);
        
        client.send_command("QUIT")?;
        client.expect_response(221)?;
        
        Ok(())
    }
    
    /// 生成性能报告
    pub fn generate_report(&self) -> Result<()> {
        println!("\n=== 性能测试报告 ===");
        
        let results = self.results.lock().unwrap();
        
        // 按操作类型分组
        let mut grouped_results: HashMap<String, Vec<&PerformanceMetrics>> = HashMap::new();
        
        for result in results.iter() {
            let operation_type = result.operation.split('_').next().unwrap_or("unknown").to_string();
            grouped_results.entry(operation_type).or_insert_with(Vec::new).push(result);
        }
        
        // 计算统计信息
        for (operation_type, metrics) in grouped_results {
            let total_count = metrics.len();
            let success_count = metrics.iter().filter(|m| m.success).count();
            let success_rate = (success_count as f64 / total_count as f64) * 100.0;
            
            let durations: Vec<Duration> = metrics.iter()
                .filter(|m| m.success)
                .map(|m| m.duration)
                .collect();
            
            if !durations.is_empty() {
                let total_duration: Duration = durations.iter().sum();
                let avg_duration = total_duration / durations.len() as u32;
                let min_duration = durations.iter().min().unwrap();
                let max_duration = durations.iter().max().unwrap();
                
                println!("操作类型: {}", operation_type);
                println!("  总次数: {}", total_count);
                println!("  成功次数: {}", success_count);
                println!("  成功率: {:.2}%", success_rate);
                println!("  平均响应时间: {:?}", avg_duration);
                println!("  最小响应时间: {:?}", min_duration);
                println!("  最大响应时间: {:?}", max_duration);
                println!();
            }
        }
        
        Ok(())
    }
    
    /// 运行完整性能测试
    pub fn run_performance_test(&self) -> Result<()> {
        println!("🚀 开始性能测试");
        
        self.test_connection_performance(10)?;
        self.test_command_performance(5)?;
        self.test_concurrent_performance(5, 3)?;
        self.test_transfer_performance()?;
        
        self.generate_report()?;
        
        println!("✅ 性能测试完成");
        Ok(())
    }
}

fn main() -> Result<()> {
    let test_suite = PerformanceTestSuite::new();
    test_suite.run_performance_test()
}
